package xxl.robotlegs.extensions.vigilance 
{
	import xxl.ioc.signals.MappingSignal;
	import xxl.robotlegs.framework.api.IContext;
	import xxl.robotlegs.framework.api.IExtension;
	import xxl.robotlegs.framework.api.ILogTarget;
	import xxl.robotlegs.framework.impl.log.LogLevel;
	import xxl.robotlegs.framework.impl.log.LogMessageParser;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class VigilanceExtension implements IExtension , ILogTarget
	{
		private const _messageParser:LogMessageParser = new LogMessageParser();
		
		public function VigilanceExtension() 
		{
			
		}
		
		public function toString():String
		{
			return "VigilanceExtension（简介：一个用来检验Inject,PostConstruct,PreDestroy等tag有没有编译进来的扩展。）";
		}
		
		private function mappingOverrideHandler(type:String,mappedType:Class,mappedName:String):void
		{
			//String, Class, String, InjectionMapping
			throw new VigilantError("Injector mapping的type[" + mappedType + "] name[" + mappedName + "]被覆写了!");
		}
		
		/* INTERFACE xxl.robotlegs.framework.api.IExtension */
		
		public function extend(context:IContext):void 
		{
			const check:MetadataChecker = context.injector.instantiateUnmapped(MetadataChecker);
			check.beginCheck();
			context.injector.destroyInstance(check);
			check.afterCheck();
			context.addLogTarget(this);
			context.injector.mappingSignal.addToMap(MappingSignal.MAPPING_OVERRIDE, mappingOverrideHandler);
		}
		
		/* INTERFACE xxl.robotlegs.framework.api.ILogTarget */
		
		public function log(source:Object, level:int, timestamp:int, message:String, params:Array = null):void 
		{
			if (level <= LogLevel.WARN)
			{
				throw new VigilantError(_messageParser.parseMessage(message, params));
			}
		}
		
	}

}
import xxl.robotlegs.framework.api.IContext;
import xxl.robotlegs.extensions.vigilance.VigilantError;
import xxl.robotlegs.framework.api.ILogger;

class MetadataChecker
{
	[Inject(optional = true)]
	public var context:IContext;
	private var logger:ILogger = null;
	
	private var flag:int = 0;
	
	public function beginCheck():void
	{
		if (context == null)
		{
			throw new VigilantError("没有context，应该是metadata里面没有Inject标签");
		}
		if (logger == null)
		{
			logger = context.getLogger(this);
		}
		if ((flag & 1) != 1)
		{
			logger.warn("metadata里面没有PostConstruct标签，部分功能可能会受到影响");
		}
	}
	
	public function afterCheck():void
	{
		if ((flag & 2) != 2)
		{
			logger.info("metadata里面没有PreDestroy标签，部分功能可能会受到影响");
		}
	}
	
	[PostConstruct]
	public function fun1():void
	{
		flag = flag | 1;
	}
	
	[PreDestroy]
	public function fun2():void
	{
		flag = flag | 2;
	}
}